<template>
    <vue-draggable-resizable :w="420" :h="620" :minw="320" :minh="320" :x="windowWidth / 2 - 210"
        :y="windowHeight / 2 - 320" :parent="true" :drag-handle="'.header'" class="ai-draggable-card">
        <!-- 关闭按钮 -->
        <div class="close-btn" @click="$emit('close')">
            <svg t="1750817345125" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
                p-id="6017" width="20">
                <path
                    d="M512 0a512 512 0 1 0 512 512A512.647282 512.647282 0 0 0 512 0z m0 958.624526a447.271808 447.271808 0 1 1 447.271808-447.271808 447.271808 447.271808 0 0 1-447.271808 447.271808z"
                    fill="#ffffff" p-id="6018"></path>
                <path
                    d="M738.548673 479.635904h-453.097346a32.364096 32.364096 0 0 0 0 64.728192h453.097346a32.364096 32.364096 0 0 0 0-64.728192z"
                    fill="#ffffff" p-id="6019"></path>
            </svg>
        </div>
        <div class="ai-chatbro">
            <div class="header">E-Y系统AI助手</div>
            <div class="messages" ref="messagesContainer">
                <div v-for="(msg, index) in messages" :key="index" class="msg-outer">
                    <div v-if="msg.role === 'user'" class="chat-bubble user-bubble">
                        {{ msg.content.trim() }}
                    </div>
                    <div v-if="msg.role === 'assistant'" class="chat-bubble assistant-bubble">
                        <div v-html="renderMarkdown(msg.content.trim())"></div>
                        <div v-if="msg.reason_content" class="reasoning" @click="toggleReasoning(index)">
                            <el-tag type="info" size="small" effect="plain">
                                {{ isReasoningOpen(index) ? '收起思考过程' : '展开思考过程' }}
                            </el-tag>
                            <div v-if="isReasoningOpen(index)" class="reasoning-content"
                                v-html="renderMarkdown(msg.reason_content.trim())"></div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="input-container">
                <el-input v-model="userMessage" placeholder="输入消息..." ref="inputRef" @keyup.enter="sendMessage" clearable />
                <el-button type="primary" @click="sendMessage" :disabled="!userMessage.trim()">发送</el-button>
            </div>
        </div>
    </vue-draggable-resizable>
</template>
  
<script setup>
import { ref, reactive, nextTick, onMounted } from 'vue'
import VueDraggableResizable from 'vue-draggable-resizable'
import 'vue-draggable-resizable/style.css'
import { ElMessage } from 'element-plus'
import { marked } from 'marked'   // 新增

const userMessage = ref('')
const messages = reactive([
    {
        role: 'assistant',
        content: '您好！我是智能助手，有什么可以帮您？\n\n**Markdown示例：**\n- 支持加粗\n- 支持`代码块`\n- [链接](https://www.neusoft.com)',
        reason_content: '这是AI的思考过程...\n\n- 支持列表\n- `代码`\n- *斜体*'
    }
])
const openReasonings = ref([])

const inputRef = ref()
const messagesContainer = ref()

const windowWidth = ref(window.innerWidth)
const windowHeight = ref(window.innerHeight)

// 渲染 markdown
function renderMarkdown(mdText) {
    return marked.parse(mdText || '')
}

function toggleReasoning(index) {
    const i = openReasonings.value.indexOf(index)
    if (i > -1) openReasonings.value.splice(i, 1)
    else openReasonings.value.push(index)
}
function isReasoningOpen(index) {
    return !openReasonings.value.includes(index)
}
function scrollToBottom() {
    const el = messagesContainer.value
    if (el) el.scrollTop = el.scrollHeight
}

async function sendMessage() {
    if (!userMessage.value.trim()) return
    messages.push({ role: 'user', content: userMessage.value })
    const currentIndex = messages.length
    messages.push({ role: 'assistant', content: '', reason_content: '' })

    const userInput = userMessage.value
    userMessage.value = ''
    await nextTick()
    inputRef.value && inputRef.value.focus()

    try {
        const response = await fetch("http://localhost:8000/chat/stream", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({ user_message: userInput })
        })

        const reader = response.body.getReader()
        const decoder = new TextDecoder("utf-8")

        let buffer = ""
        while (true) {
            const { value, done } = await reader.read()
            if (done) {
                if (buffer.trim().startsWith("data: ")) {
                    try {
                        const payload = JSON.parse(buffer.trim().slice(6))
                        handlePayload(payload, currentIndex)
                    } catch (e) {
                        console.warn("结束时解析失败：", buffer)
                    }
                }
                break
            }

            buffer += decoder.decode(value, { stream: true })
            const lines = buffer.split("\n\n")
            buffer = lines.pop() // 剩余的不完整数据留给下次处理

            for (let line of lines) {
                if (line.startsWith("data: ")) {
                    try {
                        const payload = JSON.parse(line.slice(6))
                        handlePayload(payload, currentIndex)
                    } catch (err) {
                        console.warn("解析失败的行：", line, err)
                    }
                }
            }
            await nextTick()
            scrollToBottom()
        }
    } catch (err) {
        console.error("流式对话失败：", err)
        ElMessage.error("服务连接失败")
    }
}
function handlePayload(payload, index) {
    if (payload.type === "reasoning") {
        messages[index].reason_content += payload.data
    } else if (payload.type === "reply") {
        messages[index].content += payload.data
    }
}

onMounted(() => {
    window.addEventListener('resize', () => {
        windowWidth.value = window.innerWidth
        windowHeight.value = window.innerHeight
    })
})
</script>
  
<style scoped>
.ai-draggable-card {
    z-index: 9999 !important;
    position: fixed !important;
}

/* 关闭按钮美化 */
.close-btn {
    position: absolute;
    top: 15px;
    right: 17px;
    z-index: 10;
    cursor: pointer;
    border-radius: 50%;
    padding: 3px;
    transition: background .18s;
}

.ai-chatbro {
    height: 100%;
    width: 100%;
    display: flex;
    flex-direction: column;
    border-radius: 22px;
    box-shadow: 0 8px 30px 0 rgba(60, 120, 180, 0.10), 0 2px 8px rgba(100, 180, 200, 0.07);
    background: rgba(255, 255, 255);
    overflow: hidden;
}

.header {
    background: linear-gradient(90deg, #36c7f4 0%, #73dfa6 100%);
    color: #fff;
    font-size: 22.5px;
    font-weight: 600;
    text-align: center;
    padding: 12px 0 9px 0;
    letter-spacing: 2px;
    box-shadow: 0 1px 8px rgba(50, 180, 190, 0.08);
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
}

.messages {
    flex: 1;
    overflow-y: auto;
    padding: 10px 4px 2px 4px;
    background: transparent;
}

.msg-outer {
    display: flex;
    flex-direction: column;
}

.chat-bubble {
    text-align: left !important;
    display: block;
    max-width: 76%;
    min-width: 30px;
    padding: 7px 13px;
    border-radius: 15px;
    margin: 4px 0 4px 0;
    font-size: 15px;
    line-height: 1.6;
    word-break: break-word;
    box-shadow: 0 2px 8px rgba(30, 160, 210, 0.05);
    background: linear-gradient(95deg, #e2f9fd 60%, #c8f7e2 100%);
}

.user-bubble {
    text-align: left !important;
    background: linear-gradient(95deg, #62c3fc 60%, #44e1ad 100%);
    color: white;
    border-radius: 15px 15px 6px 15px;
    margin-left: auto;
    margin-right: 6px;
}

.assistant-bubble {
    background: linear-gradient(80deg, #d8f8f0 60%, #a7e7fb 100%);
    color: #21504a;
    border-radius: 15px 15px 15px 6px;
    margin-right: auto;
    margin-left: 6px;
}

.reasoning {
    text-align: left;
    margin-top: 7px;
    font-size: 12.5px;
    cursor: pointer;
    color: #27a79c;
}

.reasoning-content {
    text-align: left !important;
    background: #effdfa;
    margin-top: 5px;
    padding: 5px 10px 5px 12px;
    border-radius: 7px;
    font-size: 13px;
    color: #297968;
    border-left: 2px solid #65e1b6;
    box-shadow: 0 1px 3px #72e2dd23;
}

.input-container {
    display: flex;
    gap: 10px;
    padding: 14px 10px 12px 10px;
    background: rgba(255, 255, 255, 0.97);
    border-top: 1px solid #e3f7fc;
    box-shadow: 0 -1px 6px rgba(80, 150, 180, 0.03);
}

.ai-draggable-card .el-input__inner {
    text-align: left !important;
}

.el-input__inner {
    border-radius: 22px !important;
    background: #f4fafd;
    box-shadow: 0 1px 6px #c4e5e416;
    border: 1px solid #a7ebe411;
    font-size: 15px;
    height: 36px;
}

.el-input__inner:focus {
    border-color: #6ddccf;
    box-shadow: 0 2px 6px #7de0b94e;
}

.el-button {
    border-radius: 18px !important;
    padding: 6px 19px;
    font-size: 15.2px;
    height: 36px;
    font-weight: 500;
    box-shadow: 0 1px 4px #8beed933;
    border: none;
    background: linear-gradient(90deg, #34c9f5 0%, #54e8b7 100%);
    color: #fff;
    letter-spacing: 1px;
}

.el-tag.el-tag--info {
    background: #e9f8f7;
    color: #18ae7d;
    border-radius: 6px;
    padding: 1.5px 7px;
    font-size: 12.5px;
}

@media (max-width: 680px) {
    .ai-chatbro {
        max-width: 100vw;
        margin: 0;
        border-radius: 0;
        box-shadow: none;
    }

    .messages {
        padding: 8px 0 2px 0;
    }

    .input-container {
        padding: 10px 4px 10px 4px;
    }

    .header {
        font-size: 16.5px;
        padding: 8px 0;
    }

    .chat-bubble {
        font-size: 13.2px;
        min-width: 36px;
        padding: 7px 9px;
    }
}

/* 隐藏 vue-draggable-resizable 拖拽激活虚线和锚点 */
.vdr .vdr-handle {
    display: none !important;
}

/* 非激活状态（未聚焦）显示默认虚线边框 */
.vdr {
    border: none !important;
    /* 你想要的颜色 */
}

/* 激活/选中时隐藏边框 */
.vdr.active,
.vdr.selected {
    border: none !important;
    box-shadow: none !important;
    outline: none !important;
}</style>
